package com.foton.bpc.all.remoting.invoker.proxy;

import com.foton.bpc.all.remoting.dto.BpcInvacation;
import com.foton.bpc.all.remoting.invoker.Invoker;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @Author RenPu
 * @Date 2023/6/12 15:12
 * @Version 1.0
 * @Description: 使用JDK得代理方法
 **/
public class InvokerInvocationHandler implements InvocationHandler {

    //代理得目标对象
    private final Invoker invoker;

    public InvokerInvocationHandler(Invoker invoker) {
        this.invoker = invoker;
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //判断Method得class，是否属于Object.class
        if(method.getDeclaringClass()==Object.class){
             method.invoke(invoker,args);
        }

        //根据方法参数以及方法名称，进行执行toString. hashCode方法等
        Class<?>[] parameterTypes = method.getParameterTypes();

        //过滤的此方法，不需要进行远程调用，所以在此处进行验证执行
        if(parameterTypes.length==0){
            if("toString".equals(method.getName())){
               return invoker.toString();
            }else if("hashCode".equals(method.getName())){
               return invoker.hashCode();
            }else if("$destroy".equals(method.getName())){
                  return null;
            }
        }else if(parameterTypes.length==1&&"equals".equals(method.getName())){
            return invoker.equals(args[0]);
        }

        //封装请求对象，例如：方法对象，接口名称，入参
        // method , invoker.getInterface().getName(),args
        BpcInvacation bpcInvacation = new BpcInvacation();
        bpcInvacation.setMethodName(method.getName());
        bpcInvacation.setParamTypes(parameterTypes);
        bpcInvacation.setArguments(args);
        return invoker.invoker(bpcInvacation);
    }
}
